<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <link rel="stylesheet" href="/js/prism.css">
    <link rel="stylesheet" href="/css/app.css">
    <title>Mysql学习一 - 叫兽</title>
    <link rel="icon" type="image/x-icon" class="js-site-favicon" href="/img/favicon.ico">
  </head>
  <body>

        <div class="container bg-white pb-5 px-5 spx-0">
            
            <h1 class="post-title">Mysql学习一</h1>




            <p>MySQL分为Server层和存储引擎层两部分</p><p>Server 层包括连接器、查询缓存、分析器、优化器、执行器等，涵盖MySQL大多数核心功能，以及所有内置函数（如日期、时间、数学和加密函数等），所有跨存储引擎的功能都在这一层实现，比如存储过程、触发器、视图等。</p><p>存储引擎层负责数据的存储和提取。其架构模式是插件式的，支持InnoDB、MyISAM、Memory等多个存储引擎。</p><h2>连接器</h2><p>客户端通过连接器和数据库连接。连接分为长连接和短连接。长连接是指连接成功后，如果客户端有持续的请求，则一直使用同一个连接，短连接则是每次执行完很少几次连接后就断开连接，下一次查询再重新建立一个。</p><p>建立间接的过程通常比较复杂，尽量使用长连接。</p><p>但是全部使用长连接后，MySQL内存涨的特别快，这是因为 MySQL在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候才释放。如果长连接积累下来，可能导致内存占用太大。</p><p>有两个方案解决这个问题：</p><ol><li>定期断开连接</li><li>MySQL5.7+，执行<code>mysql&#95;reset&#95;connection</code>来重新初始化连接资源，将连接恢复到刚刚创建完连接到状态。</li></ol><h2>执行器</h2><p>你会在数据库的慢查询日志中看到一个rows_examined的字段，表示这个语句执行过程中扫描了多少行。</p><p>innodb_flush_log_at_trx_commit这个参数设置成1的时候，表示每次事务的redo log都直接持久化到磁盘。这样可以保证MySQL异常重启之后数据不丢失。</p><p>sync_binlog这个参数设置成1的时候，表示每次事务的binlog都持久化到磁盘。这样可以保证MySQL异常重启之后binlog不丢失。</p><h2>索引</h2><p>索引对于数据库，就像书本的目录一样，方便我们快速找到书中某一个知识点。索引的出现时为了提高查询效率。</p><p>索引常见的模型：</p><ol><li>哈希表：哈希表是key-value存储数据的解构。适合像 memcached 一样的等值查询。</li><li>有序数组：有序列表，通过二分法查找对应数据。适用于静态存储索引，就是不会再修改的数据，不然中间插入数据，效率很低</li><li>搜索树：二叉树，N 叉树</li></ol><p>基于非主键索引的查询需要多扫描一颗索引树， 因此我们在应用中应尽量使用主键查询。</p><ol><li><code>select &#42; from t where id=500</code>，即为主键查询方式，则只需要id这棵B+树；</li><li><code>select &#42; from t where k=5</code>，即普通索引查询方式，则需要先搜索K 索引树，得到id的值为500，再到id索引树中搜索一次。这个过程成为回表。</li></ol><h3>自增主键</h3><p>插入主键的时候可以不指定id的值，系统会获取当前id 最大值加1作为下一条记录的 id。这样每增加一条新记录都是追加操作，都不涉及挪动其它记录，也不会触发叶子节点的分裂。</p><p>而有业务逻辑的字段做主键，则往往不容易保证有序插入，这样写数据成本相对较高。</p><p>除了考虑性能外，我们还可以从存储空间的角度来看。主键长度越小，普通索引的叶子节点就越小，普通索引占用的空间也就越小。</p><p>所以从性能和存储空间方便考量，自增主键往往是更合理的选择。</p><p>有没有什么场景适合用业务字段做主键呢？</p><ol><li>只有一个索引</li><li>该索引必须是唯一索引</li></ol><p>就是典型的 KV 场景。由于没有其他索引，就不用考虑其它索引的叶子节点的大小问题。</p><p>重建字段k 的索引<pre><code class=".language-sql">alter table t drop index k;
alter table t add index&#40;k&#41;;
</code></pre></p><p>如果重建主键索引：<pre><code class=".language-sql">alter table t drop primary key;
alter table t add primary key&#40;id&#41;;
</code></pre></p><p><code>select &#42; from t where k between 3 and 5</code>需要执行几次树的搜索操作，会扫描多少行？</p><ol><li>在k索引树上找到k=3的记录，取得id=300;</li><li>再到id索引树查到id=300对应的R3;</li><li>在 k 索引树上取下一个值k=5,取得id=500;</li><li>再回到id索引树查到id=500对应的R4;</li><li>在k索引树上取下一个值k=6，不满足条件，循环结束</li></ol><p>回到主键索引树搜索到过程称为回表，这个查询过程读了 k 索引树3条记录，回表了两次。</p><p>由于查询所需结果的数据只在主键索引上有，所以不得不回表。</p>
            <p class="text-left text-muted">2019-01-19 10:04</p>
        </div>
        <div class="container">
            <div class="row mt-4">
                <div class="col-6 text-left"><a href="/p/2019/2/10/write-a-lein-command-or-plugin/">上一篇: 写一个Lein的command/plugin/task</a></div>
                <div class="col-6 text-right"><a href="/p/2019/1/12/Transducers/">下一篇:Transducers</a></div>
            </div>
        </div>

        <button class="btn btn-link m-menu-toggle d-md-none fixed-top collapsed" type="button" data-toggle="collapse" data-target="#m-menu" aria-controls="m-menu" aria-expanded="false" aria-label="Toggle docs navigation"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" width="30" height="30" focusable="false"><title>Menu</title><path stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" d="M4 7h22M4 15h22M4 23h22"></path></svg>
        </button>
        <ul class="nav flex-column collapse fixed-top site-menu d-md-block" id="m-menu">
            <li class="nav-item">
                <a class="nav-link" href="/">首页</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="/p/list/">所有文章</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="/p/about-me/">关于我</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="https://github.com/arlicle">Github</a>
          </li>
        </ul>

        
    <div class="container mt-5">
        <h3>留言</h3>
        <div id="commentApp"></div>
    </div>
    <script>
        var AL_configs = {
            "post_id":"/p/2019/1/19/mysql-learn/",
            "appid":"847e226e8a46f64045d45312245a68ba1368a564"
        };
        (function() {
            var hm = document.createElement("script");
            hm.src = "https://comment.debugmyself.com/sc.js";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
        })();
    </script>


        <footer class="footer mt-5 pb-2">
        <div class="container text-center">
          
          <p><span class="text-black-50">Powered by <a href="https://github.com/arlicle/ablog">ablog</a> © 2019 叫兽</span></p>
          <p><span class="text-black-50"><a href="http://www.beian.miit.gov.cn/">滇ICP备10201832号-3</a></span></p>
          
        </div>
        </footer>
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
        <script src="/js/prism.js"></script>
        <script>
        $(function () {
            $('[data-toggle="tooltip"]').tooltip();
        })
        </script>
        <script type="text/x-mathjax-config">
        MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}, displayAlign: "left",scale: 180});
        </script>
        <script type="text/javascript" async
        src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_SVG" async>
        </script>
  </body>
</html>